
#ifndef incl_util_h
#define incl_util_h


#include <string.h>
#include <vector>
#include <string>
#include <Eigen/Dense>
#include "MathBasic.h"
#include "headersEigen.h"

using Eigen::VectorXd;
using Eigen::MatrixXd;

using std::vector;
using std::string;


enum class TISFLUID {STEADY=0, BDF1, BDF2, BDF3, BDF4, MidPoint, Galpha};

enum class TISSOLID {STATIC=0, BDF1, Newmark, HHTalpha, CHalpha, KDPalpha, CHalphaExplicit};

TISFLUID convert2TISFLUID(string& str);

TISSOLID convert2TISSOLID(string& str);


inline bool isAValidLine(string& line)
{
  return ( (line.size() > 1) && !( (line[0] == '!') || (line[0] == '#') || (line[0] == '%') ) );
}


template<typename T>
void findUnique(vector<T>& vect)
{
  sort(vect.begin(), vect.end());
  vect.erase(unique(vect.begin(), vect.end()), vect.end());
}


void TensorProduct(MatrixXd& A, MatrixXd& B, MatrixXd& C);


void printMatrix(MatrixXd& AA);


void printVector(VectorXd& AA);


void printVector(vector<double>&  vec);


void printVector(vector<int>&  vec);


void printVector(vector<string>&  vec);


void printVector(double*  data, int nn);


void SetTimeParametersFluid(string& tis, double rho, double dt, VectorXd& td);


void SetTimeParametersSolid(string& tis, double rho, double dt, VectorXd& td);


void create_vector(double start, double end, double incr, vector<double>& uuu);


// computes the factorial of a number 'nn'
// value is returned as 'double' to facilitate its direct use for 'divisions'
double factorial(unsigned int nn);


//Function to COMPARE TWO DOUBLE type values
inline  bool CompareDoubles (double A, double B) 
{
   double diff = A - B;

   return (diff < EPSILON) && (diff > NEG_EPSILON);
}


bool doubleGreater(double left, double right, bool orequal = false);


bool doubleLess(double left, double right, bool orequal = false);


double dotProductVecs(double* vec1, double* vec2, int N);


inline bool my_any_of(vector<int>& vecTemp, int data )
{
  bool val = false;
  for(int ii=0; ii<vecTemp.size(); ii++)
  {
    if(vecTemp[ii] == data)
    {
      val = true;
      break;
    }
  }

  return val;
}


inline int my_equal(vector<int>& vecTemp)
{
  int val = -1;
  if( std::equal(vecTemp.begin()+1, vecTemp.end(), vecTemp.begin()) )
  {
    if( vecTemp[0] == 1 )
      // val = id+1;
      val = 1;
    else
      val = 0;
  }

  return val;
}


void  split_by_whitespace(const string& input_string, vector<string>& output_string);


int  getDOFfromString(std::string& matkey);


int  getElementID_Standard(std::string& matkey);


/* Computes the rotation matrix and coordinates and solution in the local coordinate system
   for the flat shell elements
*/
int  compute_transformations_flat_shell(vector<myPoint>& coordsGlobal, MatrixXd& RotMat);

#endif






